const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs-extra');
const { v4: uuidv4 } = require('uuid');
const marked = require('marked');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
const session = require('express-session');

const app = express();

// 读取配置文件
const config = fs.readJsonSync(path.join(__dirname, 'config.json'));
const PORT = process.env.PORT || config.server.port || 3000;

// 中间件配置
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Session配置
app.use(session({
  secret: config.session.secret,
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: false, // 在生产环境中应设置为true（需要HTTPS）
    maxAge: config.session.maxAge // 24小时
  }
}));

app.use(express.static('public'));

// 速率限制
const uploadLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 10, // 限制每个IP 15分钟内最多上传10个文件
  message: '上传频率过高，请稍后再试'
});

// 确保必要的目录存在
const uploadsDir = path.join(__dirname, 'uploads');
const dataDir = path.join(__dirname, 'data');
fs.ensureDirSync(uploadsDir);
fs.ensureDirSync(dataDir);

// 文档数据存储文件
const documentsFile = path.join(dataDir, 'documents.json');
const statsFile = path.join(dataDir, 'stats.json');

// 初始化数据文件
if (!fs.existsSync(documentsFile)) {
  fs.writeJsonSync(documentsFile, []);
}
if (!fs.existsSync(statsFile)) {
  fs.writeJsonSync(statsFile, {});
}

// 配置multer用于文件上传
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, uploadsDir);
  },
  filename: (req, file, cb) => {
    const uniqueName = uuidv4() + path.extname(file.originalname);
    cb(null, uniqueName);
  }
});

const upload = multer({
  storage: storage,
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB限制
  },
  fileFilter: (req, file, cb) => {
    if (path.extname(file.originalname).toLowerCase() === '.md') {
      cb(null, true);
    } else {
      cb(new Error('只支持.md文件格式'));
    }
  }
});

// 登录验证中间件
function requireAuth(req, res, next) {
  if (req.session && req.session.isAuthenticated) {
    return next();
  } else {
    return res.status(401).json({ error: '需要登录', requireLogin: true });
  }
}

// 工具函数
function getDocuments() {
  return fs.readJsonSync(documentsFile);
}

function saveDocuments(documents) {
  fs.writeJsonSync(documentsFile, documents);
}

function getStats() {
  return fs.readJsonSync(statsFile);
}

function saveStats(stats) {
  fs.writeJsonSync(statsFile, stats);
}

function incrementViewCount(shareId) {
  const stats = getStats();
  if (!stats[shareId]) {
    stats[shareId] = { views: 0, lastViewed: null };
  }
  stats[shareId].views++;
  stats[shareId].lastViewed = new Date().toISOString();
  saveStats(stats);
  return stats[shareId].views;
}

// 路由

// 首页
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// 登录页面
app.get('/login', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'login.html'));
});

// 登录验证
app.post('/api/login', (req, res) => {
  const { username, password } = req.body;
  
  if (username === config.admin.username && password === config.admin.password) {
    req.session.isAuthenticated = true;
    req.session.username = username;
    res.json({ success: true, message: '登录成功' });
  } else {
    res.status(401).json({ error: '用户名或密码错误' });
  }
});

// 登出
app.post('/api/logout', (req, res) => {
  req.session.destroy((err) => {
    if (err) {
      return res.status(500).json({ error: '登出失败' });
    }
    res.json({ success: true, message: '登出成功' });
  });
});

// 检查登录状态
app.get('/api/auth/status', (req, res) => {
  if (req.session && req.session.isAuthenticated) {
    res.json({ authenticated: true, username: req.session.username });
  } else {
    res.json({ authenticated: false });
  }
});

// 上传文档
app.post('/api/upload', uploadLimiter, upload.single('markdown'), (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ error: '请选择要上传的Markdown文件' });
    }

    const shareId = uuidv4();
    const originalName = Buffer.from(req.file.originalname, 'latin1').toString('utf8');
    const document = {
      id: shareId,
      originalName: originalName,
      filename: req.file.filename,
      uploadTime: new Date().toISOString(),
      size: req.file.size,
      shareUrl: `/share/${shareId}`
    };

    const documents = getDocuments();
    documents.push(document);
    saveDocuments(documents);

    res.json({
      success: true,
      shareId: shareId,
      shareUrl: `${req.protocol}://${req.get('host')}/share/${shareId}`,
      message: '文档上传成功'
    });
  } catch (error) {
    console.error('上传错误:', error);
    res.status(500).json({ error: '文件上传失败' });
  }
});

// 获取文档列表（管理后台用）
app.get('/api/documents', requireAuth, (req, res) => {
  try {
    const documents = getDocuments();
    const stats = getStats();
    
    const documentsWithStats = documents.map(doc => ({
      ...doc,
      views: stats[doc.id] ? stats[doc.id].views : 0,
      lastViewed: stats[doc.id] ? stats[doc.id].lastViewed : null
    }));
    
    res.json(documentsWithStats);
  } catch (error) {
    console.error('获取文档列表错误:', error);
    res.status(500).json({ error: '获取文档列表失败' });
  }
});

// 获取最近上传的文档（公开接口，用于首页展示）
app.get('/api/recent-documents', (req, res) => {
  try {
    const documents = getDocuments();
    const stats = getStats();
    
    // 按上传时间排序，取最近的5个
    const recentDocuments = documents
      .sort((a, b) => new Date(b.uploadTime) - new Date(a.uploadTime))
      .slice(0, 5)
      .map(doc => ({
        id: doc.id,
        title: doc.originalName,
        uploadTime: doc.uploadTime,
        shareUrl: doc.shareUrl,
        views: stats[doc.id] ? stats[doc.id].views : 0
      }));
    
    res.json(recentDocuments);
  } catch (error) {
    console.error('获取最近文档错误:', error);
    res.status(500).json({ error: '获取最近文档失败' });
  }
});

// 分享页面
app.get('/share/:shareId', (req, res) => {
  try {
    const shareId = req.params.shareId;
    const documents = getDocuments();
    const document = documents.find(doc => doc.id === shareId);
    
    if (!document) {
      return res.status(404).send('文档不存在');
    }
    
    // 增加访问计数
    incrementViewCount(shareId);
    
    res.sendFile(path.join(__dirname, 'public', 'reader.html'));
  } catch (error) {
    console.error('分享页面错误:', error);
    res.status(500).send('服务器错误');
  }
});

// 获取文档内容
app.get('/api/document/:shareId', (req, res) => {
  try {
    const shareId = req.params.shareId;
    const documents = getDocuments();
    const document = documents.find(doc => doc.id === shareId);
    
    if (!document) {
      return res.status(404).json({ error: '文档不存在' });
    }
    
    const filePath = path.join(uploadsDir, document.filename);
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({ error: '文档文件不存在' });
    }
    
    const content = fs.readFileSync(filePath, 'utf8');
    const htmlContent = marked.parse(content);
    
    res.json({
      id: document.id,
      title: document.originalName,
      content: content,
      htmlContent: htmlContent,
      uploadTime: document.uploadTime
    });
  } catch (error) {
    console.error('获取文档内容错误:', error);
    res.status(500).json({ error: '获取文档内容失败' });
  }
});

// 导出为HTML
app.get('/api/export/html/:shareId', (req, res) => {
  try {
    const shareId = req.params.shareId;
    
    // 验证shareId格式
    if (!shareId || typeof shareId !== 'string') {
      return res.status(400).json({ error: '无效的分享ID' });
    }
    
    const documents = getDocuments();
    const document = documents.find(doc => doc.id === shareId);
    
    if (!document) {
      return res.status(404).json({ error: '文档不存在' });
    }
    
    const filePath = path.join(uploadsDir, document.filename);
    
    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({ error: '文档文件不存在' });
    }
    
    const content = fs.readFileSync(filePath, 'utf8');
    const htmlContent = marked.parse(content);
    
    const fullHtml = `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>${document.originalName}</title>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; max-width: 800px; margin: 0 auto; padding: 20px; }
        h1, h2, h3, h4, h5, h6 { color: #333; }
        code { background: #f4f4f4; padding: 2px 4px; border-radius: 3px; }
        pre { background: #f4f4f4; padding: 10px; border-radius: 5px; overflow-x: auto; }
        blockquote { border-left: 4px solid #ddd; margin: 0; padding-left: 20px; color: #666; }
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    ${htmlContent}
</body>
</html>`;
    
    const exportFileName = encodeURIComponent(document.originalName.replace('.md', '.html'));
    res.setHeader('Content-Type', 'text/html; charset=utf-8');
    res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${exportFileName}`);
    res.send(fullHtml);
  } catch (error) {
    console.error('导出HTML错误:', error);
    res.status(500).json({ error: '导出HTML失败' });
  }
});

// 管理后台页面
app.get('/admin', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'admin.html'));
});

// 删除文档
app.delete('/api/document/:shareId', requireAuth, (req, res) => {
  try {
    const shareId = req.params.shareId;
    const documents = getDocuments();
    const documentIndex = documents.findIndex(doc => doc.id === shareId);
    
    if (documentIndex === -1) {
      return res.status(404).json({ error: '文档不存在' });
    }
    
    const document = documents[documentIndex];
    const filePath = path.join(uploadsDir, document.filename);
    
    // 删除文件
    if (fs.existsSync(filePath)) {
      fs.unlinkSync(filePath);
    }
    
    // 从数据库中删除
    documents.splice(documentIndex, 1);
    saveDocuments(documents);
    
    // 删除统计数据
    const stats = getStats();
    delete stats[shareId];
    saveStats(stats);
    
    res.json({ success: true, message: '文档删除成功' });
  } catch (error) {
    console.error('删除文档错误:', error);
    res.status(500).json({ error: '删除文档失败' });
  }
});

// 错误处理中间件
app.use((error, req, res, next) => {
  if (error instanceof multer.MulterError) {
    if (error.code === 'LIMIT_FILE_SIZE') {
      return res.status(400).json({ error: '文件大小超过5MB限制' });
    }
  }
  res.status(500).json({ error: error.message || '服务器内部错误' });
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
  console.log(`管理后台: http://localhost:${PORT}/admin`);
});

module.exports = app;